package com.bootdo.reverseproxy.mask;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

@Service
public class Reverse {

    @Autowired
    private MaskService maskService;


    private static Logger log = LoggerFactory.getLogger(Reverse.class);
    @Value("${web.url}")
    private String basePath;


    public void modify(HttpServletRequest request, HttpServletResponse response) {
        try {
            String MOe_url = request.getRequestURI();
            log.info("MOe_url   :" + MOe_url);
            String urlString = basePath;
            urlString += MOe_url.substring(13, MOe_url.length());
            String queryString = request.getQueryString();
            log.info("queryString:" + queryString);
            urlString += queryString == null ? "" : "?" + queryString;
            log.info("Fetching >" + urlString);
            URL url = new URL(urlString);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            String methodName = request.getMethod();
            con.setRequestMethod(methodName);
            con.setConnectTimeout(10000);
            con.setReadTimeout(10000);
            con.setDoOutput(true);
            con.setDoInput(true);
            HttpURLConnection.setFollowRedirects(false);
            con.setUseCaches(true);          
            for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); ) {
                //复制请求的header信息给HttpURLConnection。
                String headerName = e.nextElement();
                con.setRequestProperty(headerName, request.getHeader(headerName));
            }

            //将post的参数key-value类型的数据以流的形式写入HttpURLConnection。
            Map<String, String[]> params = request.getParameterMap();
            queryString = "";
            for (String key : params.keySet()) {
                String[] values = params.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    queryString += key + "=" + value + "&";
                }
            }
            queryString = queryString.substring(0, queryString.length() - 1);
            byte[] queryStringBytes = queryString.getBytes();
            con.setRequestProperty("Content-Length", String.valueOf(queryStringBytes.length));
            con.connect(); //HTTP链接打开
            OutputStream cos = con.getOutputStream();
            OutputStreamWriter cosw = new OutputStreamWriter(cos);
            BufferedWriter bw = new BufferedWriter(cosw);

            bw.write(queryString);
            bw.flush();
            bw.close();
            cosw.close();
            cos.close();//写入完毕，关闭流。
            int statusCode = con.getResponseCode();
            log.info("statusCode     :" + statusCode);
            //将HttpURLConnection的body内容写入response.
            InputStream is = con.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader webToProxyBuf = new BufferedReader(isr);
            OutputStream ros = response.getOutputStream();
            OutputStreamWriter rosw = new OutputStreamWriter(ros, "utf-8");
            BufferedWriter proxyToClientBuf = new BufferedWriter(rosw);
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = webToProxyBuf.readLine()) != null) {
                 //以字符流读取HttpURLConnection。
                sb.append(line);
            }
            webToProxyBuf.close();
            isr.close();
            is.close();
            String content = sb.toString();
//            log.info("original content: " + content);
            //脱敏服务
            String maskedContent = maskService.mask(content);
//            log.info("masked content:  " + maskedContent);
            int contentLength = maskedContent.getBytes("utf-8").length;
            log.info(String.valueOf(contentLength));
            
            for (Map.Entry<String, List<String>> mapEntry : con.getHeaderFields().entrySet()) {
                //由于Content-Length已经发生的变化，所以循环里并不赋值。
                String headKey = mapEntry.getKey();
                if (headKey != null && !headKey.equals("Content-Length")) {
                    response.setHeader(headKey, (mapEntry.getValue()).get(0));
                }
            }
            //赋值Content-Length
            response.setHeader("Content-Length", String.valueOf(contentLength));
            //赋值response http status
            response.setStatus(statusCode);
            //写入脱敏的数据给response.
            proxyToClientBuf.write(maskedContent);
            proxyToClientBuf.flush();
            proxyToClientBuf.close();

            log.info("wrote content");
            con.disconnect();
        } catch (Exception e) {
            log.error("ProxyServlet:", e);
        }

    }
}
